# -*- coding: utf-8 -*-
from openerp.osv import fields
from openerp.osv import osv
from openerp import api, models
from openerp.tools import float_compare

record_model_vals = {
    'purchase.order': ['planned_delivery_date'],
    'purchase.order.line': ['expected_delivery_time'],
}

ISODATEFORMAT = '%Y-%m-%d'
######暂时注释掉记录被他人修改的检查，在毛利核对的时候会有偶发性的误报
write_original = models.BaseModel.write
@api.multi
def write(self, vals):
    if hasattr(self, "write_date") and vals.get('write_date', False) and not vals.get('create_date'):
        if self.write_date != vals.get('write_date'):
            raise osv.except_osv(
                u'错误', u'当前记录有变动，请点击右上角页码旁边的窗体视图"方框"来刷新后，再编辑')
    if hasattr(self, "_name") and self._name in record_model_vals:
        history_obj = self.env['value.history']
        [history_obj.create({'model_name': self._name,
                             'record_id': self.id,
                             'field_name': field,
                             'modify_user_id': self._uid,
                             'old_val': self[field],
                             'new_value': vals.get(field)
                             })
         for field in record_model_vals.get(self._name) if field in vals and hasattr(self, field)]
    record_id = write_original(self, vals)
    return record_id

models.BaseModel.write = write

# 观察流程执行
# signal_workflow_original = models.BaseModel.signal_workflow
# @api.multi
# def signal_workflow(self, signal):
#     result = signal_workflow_original(self, signal)
#     return result
#
# models.BaseModel.signal_workflow = signal_workflow


class value_history(osv.osv):
    _name = 'value.history'
    _columns = {
        'model_name': fields.char(u'对象名称'),
        'record_id': fields.integer(u'记录ID'),
        'field_name': fields.char(u'字段名称'),
        'modify_user_id': fields.many2one('res.users', u'用户名'),
        'old_val': fields.char(u'原值'),
        'new_value': fields.char(u'新值'),
    }

class change_related_order(osv.osv_memory):
    _name = "change.related.order"

    def fields_view_get(self, cr, uid, view_id=None, view_type='form',
                        context=None, toolbar=False, submenu=False):
        # 这个功能不是那么常用，放在更多里好点，但是这个功能只针对单条记录 所以选取多条记录的时候 就要报错
        if context is None:
            context = {}
        res = super(change_related_order, self).fields_view_get(
            cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
        if context.get('active_model', '') == 'purchase.order':

            active_ids = context.get('active_ids')
            # 检验所选采购需求中的产品是否有重复
            if len(active_ids) > 1:
                raise osv.except_osv(
                    u'错误', u'管理采购单对应的销售单的操作只针对单条记录！')
            purchase = self.pool.get("purchase.order").browse(cr, uid, context.get('active_ids'), context=context)
            if purchase.is_direct_delivery:
                raise osv.except_osv(
                    u'错误', u'直送销售订单”打勾状态时，不允许进行更多菜单里面的“采购单关联销售单的操作”，提示”请先去除“是否供应商直送打勾！')
        return res

    def set_default_related_orde(self, cr, uid,  context=None):
        # 对采购单的 关联的销售订单的字段 功能进行维护
        purchase_order = self.pool.get("purchase.order").browse(cr, uid, context.get('active_id'), context=context)
        returns_vals = []
        purchase_prodcut_id = []
        for order_line in purchase_order.order_line:
            purchase_prodcut_id.append(order_line.product_id.id)
        if purchase_order.so_ids:
            so_ids = eval(purchase_order.so_ids)
        else:
            so_ids = []
        if purchase_order:
            for sale_order_id in so_ids:
                detail_text = []
                sale_order = self.pool.get('sale.order').browse(cr, uid, sale_order_id, context=context)
                sale_order_line_ids_str = []
                for sale_order_line in sale_order.order_line:
                    if sale_order_line.product_id.id in purchase_prodcut_id:
                        # 生成采购单和销售订单的关联性的 text 的拼接
                        detail_text.append("%s   (%s) " % (sale_order_line.product_id.name, int(sale_order_line.product_uom_qty)))
                        sale_order_line_ids_str.append(sale_order_line.id)
                returns_vals.append([0, False, {'sale_order_id': sale_order_id, 'related_order_detail': '\n'.join(detail_text),
                                                'user_id': sale_order.user_id.id, 'sale_order_line_ids_str': sale_order_line_ids_str,
                                                'partner_id': sale_order.partner_id.id, 'expected_delivery_time': sale_order.expected_delivery_time}])
        context = dict({'purchase_order_id': context.get('active_id')}, **context)
        return returns_vals

    def confirm_change_order(self, cr, uid, ids, context=None):
        change_related_order = self.browse(cr, uid, ids, context=context)
        so_ids, so_names = [], []
        for order_line in change_related_order.related_order_line:
            so_ids.append(order_line.sale_order_id.id)
            so_names.append(order_line.sale_order_id.name)
            if not order_line.sale_order_line_ids_str:
                raise osv.except_osv(u'错误', u'销售订单有变更， 请删除并重新添加之前的销售订单:' + order_line.sale_order_id.name)
            self.pool.get('sale.order.line').write(cr, uid, list(eval(order_line.sale_order_line_ids_str)),
                                                   {'purchase_uid': uid}, context=context)
        self.pool.get("purchase.order").write(cr, uid, context.get('active_id'), {'so_ids': str(so_ids or '[]') or False}, context=context)
        return True
    _columns = {
        "related_order_line": fields.one2many('change.related.order.line', 'related_order', string="关联销售订单列表"),
        'purchase_order_id': fields.integer(u"采购单id"),
    }
    _defaults = {
        'related_order_line': set_default_related_orde,
        'purchase_order_id': lambda self, cr, uid, ctx=None: ctx.get('active_id'),
    }


class change_related_order_line(osv.osv_memory):
    _name = "change.related.order.line"

    def onchange_sale_order_id(self, cr, uid, ids, sale_order_id, purchase_order_id, context=None):
        # 选取 对应的销售订单 根据销售订单 和采购单的产品重合的个数生成 文本数据,填充在销售订单的 后边
        purchase_order = self.pool.get("purchase.order").browse(cr, uid, purchase_order_id, context=context)
        purchase_prodcut_id = []
        for order_line in purchase_order.order_line:
            purchase_prodcut_id.append(order_line.product_id.id)
        sale_order = self.pool.get('sale.order').browse(cr, uid, sale_order_id, context=context)
        detail_text = []
        sale_order_line_ids =[]
        for sale_order_line in sale_order.order_line:
            if sale_order_line.product_id.id in purchase_prodcut_id:
                detail_text.append("%s   (%s) " % (sale_order_line.product_id.name, int(sale_order_line.product_uom_qty)))
                sale_order_line_ids.append(sale_order_line.id)
        return {'value': {'related_order_detail': '\n'.join(detail_text), 'user_id': sale_order.user_id.id,
                          'partner_id': sale_order.partner_id.id,
                          'expected_delivery_time': sale_order.expected_delivery_time,
                          'sale_order_line_ids_str': str(sale_order_line_ids)}}
    _columns = {
        'sale_order_id': fields.many2one('sale.order', u'销售订单'),
        'related_order_detail': fields.text(u'订单关联详情'),
        'related_order': fields.many2one('change.related.order'),
        'user_id': fields.many2one('res.users', u'销售员'),
        'partner_id': fields.many2one('res.partner', u'客户'),
        'expected_delivery_time': fields.datetime(u'预计发货时间'),
        'sale_order_line_ids_str': fields.char(u'关联的销售订单行')
    }


class share_user_wizard(osv.osv_memory):
    _name = 'share.user.wizard'
    # 把客户批量分享给用户
    # 同时要分享客户对应的联系人

    def confirm_share_partner_to_others(self, cr, uid, ids, context):
        partner_obj = self.pool.get('res.partner')
        share_partner = self.browse(cr, uid, ids, context=context)
        partner_obj.write(cr, uid, context.get('active_ids'), {
                          'share_to_uid': share_partner.user_id.id}, context=context)
        partner_ids = []
        for partner in partner_obj.browse(cr, uid, context.get('active_ids'), context=context):
            partner_ids.extend(
                [partner_contact.contacts_id.id for partner_contact in partner.child_contacts_ids])
        partner_obj.write(cr, uid, partner_ids, {
                          'share_to_uid': share_partner.user_id.id}, context=context)
        return True
    _columns = {
        'user_id': fields.many2one('res.users', string=u'分享给'),
        'share_qty': fields.integer(u'本次分享客户的数量'),
    }
    _defaults = {
        'share_qty': lambda s, c, u, ctx={}: len(ctx.get("active_ids", [])),
    }


class sale_order_product_expenses(osv.osv):
    _name = "sale.order.product.expenses"
    _columns = {
        'product_id': fields.many2one('product.product', u'产品'),
        'type': fields.selection([('packing', u'包装'), ('expressage', u'运费')], u'类型'),
        'product_price_sum_start': fields.float(u'产品价格区间(大于)'),
        'product_price_sum_end': fields.float(u'产品价格区间(小于)'),
        'standard_free_cost': fields.float(u'公司承担费用'),
        'sale_free_cost': fields.float(u'销售承担费用'),
    }


class stock_change(osv.osv):
    _inherit = "stock.change"

    def get_out_line_cost(self, cr, uid, change_row, context=None):
        out_amt = 0
        for line in change_row.move_out_lines:
            inventory_value = 0.0
            out_qty = 0
            # 计算附加成本行的成本总金额
            if line.product_id.type == 'service':
                inventory_value = line.product_id.standard_price * line.product_uom_qty
                out_qty = line.product_uom_qty
            # 计算库存类型产品的成本总金额
            for move_quants in line.quant_ids:
                inventory_value += move_quants.cost * move_quants.qty
                out_qty += move_quants.qty

            line.write({'price_unit': inventory_value * 1.0 / out_qty})
            out_amt += inventory_value
        return out_amt

    def dftg_cost_handle(self, cr, uid, change_row, context=None):
        move_obj = self.pool.get("stock.move")
        move_out_ids = [x.id for x in change_row.move_out_lines]
        move_in_ids = [x.id for x in change_row.move_in_lines]
        ''' 先判断入库或出库行中产品数量是否<=0，如果是则给出警告。在判断产品可用性之前，先将入库和出库行中的状态修改为确认。'''
        out_amt = 0  # 出库产品的总金额
        move_obj.action_done(cr, uid, move_out_ids, context=context)
        out_amt = self.get_out_line_cost(cr, uid, change_row, context=context)

        ''' 入库行 '''
        # 入库产品的总金额 就是出库产品总金额。
        for line in change_row.move_in_lines:
            ''' 根据产生的出库 quants 来分摊入库产品的单价，填充到入库行的单价中 '''
            line.write({'price_unit': out_amt / line.product_uom_qty})
        move_obj.action_done(cr, uid, move_in_ids, context=context)
        change_row.write({'amount': out_amt, 'state': 'done'})
        return True

    def action_approve(self, cr, uid, ids, context=None):
        '''  点击审批按钮，状态由待审批变为已审批，产品数量也做相应增减    '''
        assert (len(ids) == 1), 'This option should only be used for a single id at a time'
        change_row = self.browse(cr, uid, ids, context=context)
        ''' 如果出库行或入库行为空，则给出警告 '''
        if not change_row.move_out_lines or not change_row.move_in_lines:
            raise osv.except_osv(u'警告！', u'请输入出库详情或入库详情！')
        move_out_ids = [x.id for x in change_row.move_out_lines]
        move_in_ids = [x.id for x in change_row.move_in_lines]
        if len(move_in_ids) == 1 and len(move_out_ids) >= 1:
            return_val = self.dftg_cost_handle(cr, uid, change_row, context=context)
        else:
            return_val = super(stock_change, self).action_approve(cr, uid, ids, context=context)
        return return_val


class change_sale_order(osv.osv_memory):
    _name = 'change.sale.order'
    _columns = {
        'order_id': fields.many2one('sale.order', string='销售订单'),
        'line_ids': fields.one2many('change.sale.order.line', 'change_id', string="变更行列表")
    }

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        return_vals = super(change_sale_order, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type,
                                                                    context=context, toolbar=toolbar, submenu=submenu)
        if context and context.get('active_ids', False):
            if len(context.get('active_ids')) > 1:
                raise osv.except_osv(_('警告!'), _("只能选择一个销售订单!"))


        record_id = context and context.get('active_ids', False) or []
        order_obj = self.pool.get('sale.order')
        for order in order_obj.browse(cr, uid, record_id, context=context):
            if len([invoice.id for invoice in order.invoice_ids]) > 1:
                raise osv.except_osv(u'警告!', u"有多个发票不能修改数量!")
            if not order.shipment_completion:
                raise osv.except_osv(u'警告!', u"此订单没有发货完成，不能进行操作!")
            for line in order.order_line:
                if u'商城' in line.product_id.name:
                    break
            else:
                raise osv.except_osv(u'警告!', u"此订单不属于商城订单，不能进行操作!")
        # picking_ids = self.pool.get('stock.picking').search(cr, uid, [('so_id', '=', context.get('active_id', False)),
        #                                                               ('state', '=', 'done')], context=context)
        # if len(picking_ids) != 1:
        #     raise osv.except_osv(u'警告!', u"有多个出库单不能修改数量!")

        return return_vals

    def confirm_change_sale_order(self, cr, uid, ids, context=None):
        for change_order in self.browse(cr, uid, ids, context=context):
            for line in change_order.line_ids:
                if float_compare(line.product_qty * line.price_unit, line.order_line_id.price_subtotal, 2) != 0:
                    raise osv.except_osv(u'警告!', u"只能调整销售订单行的产品得数量和价格，总价不能受影响!")
                cr.execute("""UPDATE sale_order_line SET product_uom_qty=%s,price_unit=%s,
                              delivered_qty=%s, shipped_qty=%s, delivery_quantity_qty=0 WHERE id=%s""" %
                           (line.product_qty, line.price_unit, line.product_qty,
                            line.product_qty, line.order_line_id.id))
        return True

    def _set_sale_order(self, cr, uid, context=None):
        if context.get('active_id'):
            return context.get('active_id')
        else:
            return False

    def _set_line_ids(self, cr, uid, context=None):
        line_ids = []
        for order in self.pool.get('sale.order').browse(cr, uid, context.get('active_id'), context=context):
            for line in order.order_line:
                line_ids.append((0, 0, {'order_line_id': line.id,
                                        'product_qty': line.product_uom_qty,
                                        'origin_price': line.origin_price,
                                        'price_unit': line.price_unit}))
        return line_ids

    _defaults = {
        'order_id': _set_sale_order,
        'line_ids': _set_line_ids,
    }


class change_sale_order_line(osv.osv_memory):
    _name = 'change.sale.order.line'
    _columns = {
        'change_id': fields.many2one('change.sale.order'),
        'order_line_id': fields.many2one('sale.order.line', '销售订单行'),
        'product_qty': fields.integer('数量'),
        'price_unit': fields.integer('单价'),
        'origin_price': fields.integer('原价'),
    }


class express_cost(osv.osv):
    _name = 'express.cost'
    _columns = {
        'express_code': fields.char(u'快递单号'),
        'express_cost': fields.char(u'快递费用'),
    }

